package com.lonely.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lonely.common.core.domain.BaseEntity;
import com.lonely.common.core.domain.Select;
import com.lonely.common.core.page.Condition;
import com.lonely.common.enums.CommonStatus;
import com.lonely.common.enums.DataScope;
import com.lonely.common.threadlocals.DataPermissionThreadLocal;
import com.lonely.common.utils.SecurityUtils;
import com.lonely.system.domain.dto.customer.SysCustomerPageQueryDto;
import com.lonely.system.domain.dto.customer.SysCustomerSubmitDto;
import com.lonely.system.domain.entity.SysCustomer;
import com.lonely.system.domain.vo.system.customer.SysCustomerPageQueryVo;
import com.lonely.system.mapper.SysCustomerMapper;
import com.lonely.system.service.ISysCustomerService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author: 黄志标
 * @date: 2025/5/27 11:36
 * @description:
 */
@Service
public class SysCustomerServiceImpl extends ServiceImpl<SysCustomerMapper, SysCustomer> implements ISysCustomerService {

    /**
     * 分页查询
     *
     * @param queryDto
     * @return
     */
    @Override
    public Page<SysCustomerPageQueryVo> page(SysCustomerPageQueryDto queryDto) {
        DataPermissionThreadLocal.setDataPermission(DataScope.FACTORY, "factory_id");
        Page<SysCustomer> page = Condition.page(queryDto);
        LambdaQueryWrapper<SysCustomer> queryWrapper = new LambdaQueryWrapper<SysCustomer>().like(StrUtil.isNotBlank(queryDto.getCustomerName()), SysCustomer::getCustomerName, queryDto.getCustomerName())
                .eq(queryDto.getStatus() != null, SysCustomer::getStatus, queryDto.getStatus())
//                .eq(SysCustomer::getFactoryId, SecurityUtils.getFactoryId())
                .like(StrUtil.isNotBlank(queryDto.getPhone()), SysCustomer::getPhone, queryDto.getPhone());

        Page<SysCustomer> customerPage = super.page(page, queryWrapper);
        Page<SysCustomerPageQueryVo> resultPage = new Page<>();
        BeanUtils.copyProperties(customerPage, resultPage);

        if (CollUtil.isNotEmpty(customerPage.getRecords())) {
            resultPage.setRecords(customerPage.getRecords().stream().map(x -> {
                SysCustomerPageQueryVo sysCustomerPageQueryVo = new SysCustomerPageQueryVo();
                BeanUtils.copyProperties(x, sysCustomerPageQueryVo);
                return sysCustomerPageQueryVo;
            }).collect(Collectors.toList()));
        }
        return resultPage;
    }

    /**
     * 创建客户
     *
     * @param submitDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(SysCustomerSubmitDto submitDto) {
        Assert.isNull(submitDto.getId(), "参数错误(id)");
        checkCustomer(submitDto);

        SysCustomer sysCustomer = new SysCustomer();
        BeanUtils.copyProperties(submitDto, sysCustomer);
        sysCustomer.setFactoryId(SecurityUtils.getFactoryId());
        sysCustomer.setCreateBy(SecurityUtils.getUserId());
        sysCustomer.setUpdateBy(SecurityUtils.getUserId());
        super.save(sysCustomer);
    }

    /**
     * 编辑客户
     *
     * @param submitDto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(SysCustomerSubmitDto submitDto) {
        Assert.notNull(submitDto.getId(), "参数错误(id)");
        checkCustomer(submitDto);
        SysCustomer oldCustomer = super.getById(submitDto.getId());
        BeanUtils.copyProperties(submitDto, oldCustomer);
        oldCustomer.setUpdateBy(SecurityUtils.getUserId());
        super.updateById(oldCustomer);
    }

    /**
     * 启用客户
     *
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void enabled(Long id) {
        SysCustomer sysCustomer = super.getById(id);
        Assert.notNull(sysCustomer, "客户不存在");
        sysCustomer.setStatus(CommonStatus.ENABLE.code);
        super.updateById(sysCustomer);
    }

    /**
     * 禁用客户
     *
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void disable(Long id) {
        SysCustomer sysCustomer = super.getById(id);
        Assert.notNull(sysCustomer, "客户不存在");
        sysCustomer.setStatus(CommonStatus.DISABLE.code);
        super.updateById(sysCustomer);
    }

    /**
     * 获取客户下拉列表
     *
     * @return
     */
    @Override
    public List<Select> getCustomerSelect() {
        DataPermissionThreadLocal.setDataPermission(DataScope.FACTORY, "factory_id");
        return super.list(new LambdaQueryWrapper<SysCustomer>()
//                        .eq(SysCustomer::getFactoryId, SecurityUtils.getFactoryId())
                        .eq(SysCustomer::getStatus, CommonStatus.ENABLE.code))
                .stream().map(customer -> new Select().setLabel(customer.getCustomerName()).setValue(String.valueOf(customer.getId())))
                .collect(Collectors.toList());
    }

    /**
     * 获取客户最大范围
     *
     * @param customerIds
     * @return
     */
    @Override
    public Map<Long, String> getCustomerMaxRangeMap(List<Long> customerIds) {
        if (CollUtil.isEmpty(customerIds)) {
            return new HashMap<>();
        }
        return super.listByIds(customerIds).stream().collect(Collectors.toMap(BaseEntity::getId, x -> StrUtil.blankToDefault(x.getMaxRange(), "0"), (a, b) -> a));
    }

    /**
     * 校验客户信息
     *
     * @param submitDto
     */
    private void checkCustomer(SysCustomerSubmitDto submitDto) {

        // 1. 校验客户名称是否重复
        int count = super.count(new LambdaQueryWrapper<SysCustomer>()
                .eq(SysCustomer::getCustomerName, submitDto.getCustomerName())
                .eq(SysCustomer::getFactoryId, SecurityUtils.getFactoryId())
                .ne(submitDto.getId() != null, SysCustomer::getId, submitDto.getId()));
        Assert.isTrue(count == 0, "该客户已存在");

        //2. 校验客户id是否正确
        if (submitDto.getId() != null) {
            SysCustomer sysCustomer = super.getById(submitDto.getId());
            Assert.notNull(sysCustomer, "客户不存在");
        }
    }
}
